package com.example.onlinetaxi.BaiDuMap;

import android.app.Activity;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.example.onlinetaxi.LocalStroage.LocalStorage;
import com.example.onlinetaxi.R;
import com.example.onlinetaxi.callback.DriverCallBack.ILocationChange;
import com.example.onlinetaxi.callback.MapCallBack.IPickLocation;
import com.example.onlinetaxi.BaiDuMap.Listeners.MyOrientationListener;
import com.example.onlinetaxi.BaiDuMap.Util.GeoReverse;
import com.example.onlinetaxi.BaiDuMap.Util.GetCustomStyleFilePath;

// 使用单例模式创建管理者
public class BaiDuMapManager {

    public static BaiDuMapManager baiDuMapManager = new BaiDuMapManager();

    // 上下文
    private Activity activity;
    // 地图
    public MapView mMapView;
    public BaiduMap mBaiduMap;
    // 定位功能
    private LocationClient mLocationClient;
    private MyLocationListener myListener = new MyLocationListener();
    public boolean isFirstLocate = true;//是否是首次定位
    // 是否开启地理选点
    private boolean isGeo = true;
    // 当前经纬度
    private LatLng latLng;
    private double mLatitude;  // 经度
    private double mLongitude;  // 纬度
    private MyLocationData locData;  // 定位信息
    // 当前城市
    private String city;
    // 当前地点
    private String address;
    // 方向确认功能
    private float mCurrentX;
    private MyOrientationListener myOrientationListener;
    // 用于设置个性化地图的样式文件
    private static final String MAP_STYLE = "map_style.sty";
    // 用来设置城市
    private IPickLocation iPickLocation;
    // 用来更新司机定位信息
    private ILocationChange locationChange;

    private BaiDuMapManager() {

    }

    public void setActivity(Activity activity) {
        this.activity = activity;
    }

    // 设置地图控件时，同时进行初始化
    public void setMapView(MapView mapView) {
        mMapView = mapView;
        mBaiduMap = mMapView.getMap();

        // 初始化地图
        initMap();

        // 开启方向服务
        autoDirection();
    }

    public void isLocate(Boolean flag) {
        // 表示第一次定位地图
        isFirstLocate = flag;
    }

    public void isOpenGeoReverse(Boolean flag) {
        isGeo = flag;
    }

    public void setiCityLocation(IPickLocation iPickLocation) {
        this.iPickLocation = iPickLocation;
    }

    public void setLocationChange(ILocationChange locationChange) {
        this.locationChange = locationChange;
    }

    private void initGeoReverse() {
        GeoReverse geoReverse = new GeoReverse();
        geoReverse.setiCityLocation(new IPickLocation() {
            @Override
            public void getPickInfo(ReverseGeoCodeResult reverseGeoCodeResult) {
                iPickLocation.getPickInfo(reverseGeoCodeResult);
            }
        });
        geoReverse.init();
    }

    // 初始化地图
    private void initMap() {
        // 取消缩放按钮
        mMapView.showZoomControls(false);
        // 设置地图缩放级别
        MapStatus.Builder builder = new MapStatus.Builder();
        builder.zoom(20.0f);  // 缩放等级为20，适合打车服务
        mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        // 默认显示普通地图
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        // 设置图层参数
        MyLocationConfiguration myLocationConfiguration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, null);
        mBaiduMap.setMyLocationConfiguration(myLocationConfiguration);

        // 获取.sty文件路径
        String customStyleFilePath = GetCustomStyleFilePath.getCustomStyleFilePath(activity, MAP_STYLE);
        // 设置个性化地图样式文件的路径和加载方式
        mMapView.setMapCustomStylePath(customStyleFilePath);
        // 动态设置个性化地图样式是否生效
        mMapView.setMapCustomStyleEnable(true);

        // 定位初始化
        try {
            mLocationClient = new LocationClient(activity.getApplicationContext());     //声明LocationClient类
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // 配置定位SDK参数
        initLocation();
        mLocationClient.registerLocationListener(myListener);    //注册监听函数
        mLocationClient.start();//开启定位
        mLocationClient.requestLocation();//图片点击事件，回到定位点
    }

    public void autoDirection() {
        // 方向传感器
        myOrientationListener = new MyOrientationListener(activity);
        myOrientationListener.setmOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
            @Override
            public void onOrientationChanged(float x) {
                // 方向更新在MyLocationListener类中进行
                mCurrentX = x;
            }
        });
        // 启动方向传感器
        myOrientationListener.start();
    }

    // 实现BDLocationListener接口,BDLocationListener为结果监听接口，异步获取定位结果
    private class MyLocationListener implements BDLocationListener {
        @Override
        public void onReceiveLocation(final BDLocation location) {
            // 获取定位信息
            city = location.getCity();
            address = location.getPoiList().get(0).getName();
            latLng = new LatLng(location.getLatitude(), location.getLongitude());

            // 位置改变更新UI
            if (LocalStorage.type.equals("driver")) {
                locationChange.changeDriverUi(city, address, latLng);
            }

            // 构造定位数据
            mLatitude = location.getLatitude();
            mLongitude = location.getLongitude();
            locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    .direction(mCurrentX)// 此处设置开发者获取到的方向信息，顺时针0-360s
                    .latitude(mLatitude)
                    .longitude(mLongitude).build();
            mBaiduMap.setMyLocationData(locData);// 设置定位数据

            if (isFirstLocate) {
                isFirstLocate = false;
                LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
                MapStatus.Builder builder = new MapStatus.Builder();
                builder.target(latLng).zoom(18.0f);
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

                if (isGeo) {
                    // 启动地图反编码功能(在获取定位之后进行)
                    MyGeoCoder.myGeoCoder.setActivity(activity);
                    initGeoReverse();
                }
            }
        }
    }

    // 配置定位功能
    private void initLocation() {
        // 通过LocationClientOption设置LocationClient相关参数
        LocationClientOption option = new LocationClientOption();
        option.setCoorType("bd09ll");//可选，coorType - 取值有3个： 返回国测局经纬度坐标系：gcj02 返回百度墨卡托坐标系 ：bd09 返回百度经纬度坐标系 ：bd09ll
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setOpenGps(true); // 是否打开gps进行定位
        option.setLocationNotify(true);//可选，默认false，设置是否当GPS有效时按照1S/1次频率输出GPS结果
        option.setScanSpan(1000);//可选，设置的扫描间隔，单位是毫秒，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.setNeedDeviceDirect(true);//在网络定位时，是否需要设备方向- true:需要 ; false:不需要。默认为false
        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        option.setIgnoreKillProcess(false);//可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation
        // .getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤GPS仿真结果，默认需要
        option.setNeedDeviceDirect(true);// 设置获取方向
        //设置locationClientOption
        mLocationClient.setLocOption(option);
    }

    public void backToLocation() {
        //把定位点再次显现出来
        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(latLng);
        mBaiduMap.animateMapStatus(mapStatusUpdate);
    }

    public void setCenter(LatLng latLng) {
        // 更改地图中心点
        MapStatus mMapStatus = new MapStatus.Builder()
                .target(latLng)
                .zoom(18)
                .build();
        //定义MapStatusUpdate对象，以便描述地图状态将要发生的变化
        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);

        mBaiduMap.setMapStatus(mMapStatusUpdate);
    }

    public LatLng getLocation() {
        return latLng;
    }

    public String getCity() {
        return city;
    }

    public String getAddress() {
        return address;
    }

    // 进行内容的销毁
    public void destroy() {
        if (null != mMapView) {
            mMapView.onDestroy();
            mLocationClient.stop();
            mBaiduMap.setMyLocationEnabled(false);
            mMapView = null;
        }
    }
}
